package beautiful.butterfly.server.application;

import beautiful.butterfly.server.httpserver.handler.HttpConst;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Map;
import java.util.Properties;


@Slf4j

public class Environment {

    //
    private static final String CLASSPATH_PREFIX = "classpath:";
    private static final String FILE_PREFIX = "file:";
    private static final String URL_PREFIX = "url:";
    //
    private Properties properties = new Properties();

    //
    public static ClassLoader getCurrentThreadClassLoader() {
        ClassLoader classLoader = null;
        try {
            classLoader = Thread.currentThread().getContextClassLoader();
        } catch (Exception ignored) {
        }
        if (classLoader == null) {
            classLoader = Environment.class.getClassLoader();
            if (classLoader == null) {
                try {
                    // getCurrentThreadClassLoader() returning null indicates the bootstrap ClassLoader
                    classLoader = ClassLoader.getSystemClassLoader();
                } catch (Exception e) {
                    // Cannot access system ClassLoader - oh well, maybe the caller can live with null...
                }
            }
        }
        return classLoader;
    }

    //public Environment empty() {
    //   return new Environment();
    //}

    public static Environment of(@NonNull Properties properties) {
        System.out.println("属性:" + properties);
        Environment environment = new Environment();
        environment.properties.putAll(properties);
        return environment;
    }

    public static Environment of(@NonNull Map<String, String> map) {
        Environment environment = new Environment();
        for (String key :
                map.keySet()) {
            environment.properties.setProperty(key, map.get(key));
        }

        return environment;
    }

    public static Environment of(@NonNull String location) {
        if (location.startsWith(CLASSPATH_PREFIX)) {
            location = location.substring(CLASSPATH_PREFIX.length());
            return loadClasspath(location);
        } else if (location.startsWith(FILE_PREFIX)) {
            location = location.substring(FILE_PREFIX.length());
            return of(new File(location));
        } else if (location.startsWith(URL_PREFIX)) {
            location = location.substring(URL_PREFIX.length());
            try {
                return of(new URL(location));
            } catch (MalformedURLException e) {
                e.printStackTrace();
                return null;
            }
        } else {
            return loadClasspath(location);
        }
    }

    private static Environment loadClasspath(@NonNull String classpath) {
        String path = classpath;
        if (classpath.startsWith(HttpConst.SLASH)) {
            path = classpath.substring(1);
        }
        InputStream inputStream = getCurrentThreadClassLoader().getResourceAsStream(path);
        if (null == inputStream) {
            return new Environment();
        }
        return of(inputStream);
    }

    public static Environment of(@NonNull File file) {
        try {
            return of(Files.newInputStream(Paths.get(file.getPath())));
        } catch (IOException e) {
            throw new IllegalStateException(e);
        }
    }

    public static Environment of(@NonNull URL url) {
        try {
            return of(url.openStream());
        } catch (UnsupportedEncodingException e) {
        } catch (IOException e) {
            throw new IllegalStateException(e);
        }
        return null;
    }

    private static Environment of(@NonNull InputStream inputStream) {
        try {
            Environment environment = new Environment();
            environment.properties.load(new InputStreamReader(inputStream, "UTF-8"));
            return environment;
        } catch (IOException e) {
            throw new IllegalStateException(e);
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (Exception e) {

                } finally {

                }
            }

        }
    }

    public static String pathFix(String path) {
        return path.replace("\\", File.separator).replace("/", File.separator);
    }

    public Properties getProperties() {
        return properties;
    }

    //
    public Environment set(@NonNull String key, @NonNull Object value) {
        properties.put(key, value.toString());
        return this;
    }

    public Object get(String key) {
        return properties.getProperty(key);
    }

    public Object get(String key, String defaultValue) {
        Object value = get(key);
        if (value == null) {
            return defaultValue;
        } else {
            return value;
        }
    }

    public boolean getBoolean(String key, boolean $boolean) {
        String value = (String) get(key);
        if (value != null) {
            return Boolean.valueOf(value);
        } else {
            return $boolean;
        }

    }

    public int getInt(String key, int defaultValue) {
        String value = (String) get(key);

        if (value != null) {
            return Integer.parseInt(value);
        } else {
            return defaultValue;
        }
    }

    public String getString(String key, String defaultValue) {
        String value = (String) get(key);
        if (value != null) {
            return value;
        } else {
            return defaultValue;
        }
    }

}
